package com.yakaten.login;

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.CookieHandler;
import java.net.CookiePolicy;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.IOUtils;
import org.seasar.framework.log.Logger;
import org.seasar.framework.util.ResourceUtil;

import com.yakaten.exception.AmazonException;

public class AmazonLogin {

	static Logger logger = Logger.getLogger(AmazonLogin.class);

	private static final String REGEX_FORM = "<form.+?action=\"(.+?)\" .+?>(.+?)</form>";
	private static final Pattern PATTERN_FORM= Pattern
	.compile(REGEX_FORM);

	private static final String REGEX_INPUTHIDDEN = "<input type=\"hidden\".*?>";
	private static final Pattern PATTERN_INPUTHIDDEN= Pattern
	.compile(REGEX_INPUTHIDDEN);

	private static final String REGEX_NAME = "name=\"(.+?)\"";
	private static final Pattern PATTERN_NAME= Pattern
	.compile(REGEX_NAME);

	private static final String REGEX_VALUE = "value=\"(.+?)\"";
	private static final Pattern PATTERN_VALUE= Pattern
	.compile(REGEX_VALUE);

	private Map<String,String> doLoginStep0(String userName, String password) throws AmazonException {
		OutputStreamWriter out = null;
		BufferedReader bufferedReader = null;
		HttpURLConnection connection = null;
		Map<String,String> hiddenMap = new HashMap<String,String>();
		try {
			String LOGIN_URL0 = ResourceUtil
					.getProperties("yakaten.properties").getProperty(
							"amazon.login.url0");
			URL loginUrl = new URL(LOGIN_URL0);
			connection = (HttpURLConnection) loginUrl.openConnection();
			connection.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2");
			connection.connect();

			InputStream urlStream = connection.getInputStream();
			connection.getHeaderField("Set-Cookie");
			bufferedReader = new BufferedReader(new InputStreamReader(
					urlStream, "shift_jis"));
			String ss = null;
			StringBuffer total = new StringBuffer();
			while ((ss = bufferedReader.readLine()) != null) {
				total.append(ss);
			}

			Matcher matcherForm = PATTERN_FORM.matcher(total);
			String action = "";
			String formStr="";
			if (matcherForm.find()) {
				action = matcherForm.group(1);
				formStr =matcherForm.group(2);
				hiddenMap.put("formaction", action);
			}

			Matcher matcherInputHidden= PATTERN_INPUTHIDDEN.matcher(formStr);

			while (matcherInputHidden.find()) {
				String inputHidden = matcherInputHidden.group();
				Matcher matcherName= PATTERN_NAME.matcher(inputHidden);
				String name ="";
				if (matcherName.find()) {
					name = matcherName.group(1);
				}

				Matcher matcherValue= PATTERN_VALUE.matcher(inputHidden);
				String value="";
				if (matcherValue.find()) {
					value = matcherValue.group(1);
				}
				hiddenMap.put(name, URLEncoder.encode(value,"shift_jis"));
			}
		} catch (MalformedURLException e) {
			throw new AmazonException(e);
		} catch (IOException e) {
			throw new AmazonException(e);
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (bufferedReader != null) {
				try {
					bufferedReader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (connection != null) {
				connection.disconnect();
			}
		}

		return hiddenMap;
	}

	private String getParma(Map<String,String> valueMap){
		StringBuffer parm = new StringBuffer("");
		Iterator<String> it = valueMap.keySet().iterator();
		while(it.hasNext()){
			String key = it.next();
			String value = valueMap.get(key);
			parm.append(key+"="+value+"&");
		}
		parm.deleteCharAt(parm.length()-1);
		return parm.toString();
	}
	private boolean doLoginStep1(Map<String,String> valueMap) throws AmazonException {
		boolean result = false;
		BufferedReader bufferedReader = null;
		HttpURLConnection connection = null;
		OutputStreamWriter out = null;
		try {
			String LOGIN_URL1 = valueMap.get("formaction");
			valueMap.remove("formaction");
			URL loginUrl = new URL(LOGIN_URL1);

			connection = (HttpURLConnection) loginUrl.openConnection();
			connection.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2");
			connection.setDoOutput(true);

			out = new OutputStreamWriter(connection.getOutputStream(),
					"shift_jis");

			String para = this.getParma(valueMap);
			out.write(para);

			out.flush();

			InputStream urlStream = connection.getInputStream();
			bufferedReader = new BufferedReader(new InputStreamReader(
					urlStream, "shift_jis"));
			String ss = null;
			StringBuffer total = new StringBuffer();
			while ((ss = bufferedReader.readLine()) != null) {
				total.append(ss);
			}

		} catch (MalformedURLException e) {
			throw new AmazonException(e);
		} catch (IOException e) {
			throw new AmazonException(e);
		} finally {
			if (bufferedReader != null) {
				try {
					bufferedReader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (connection != null) {
				connection.disconnect();
			}

			if(out!=null){
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

		return result;
	}

	public boolean doLogin(String userName, String password) throws AmazonException {
		CorrectedCookieManager manager = new CorrectedCookieManager();
		manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
		CookieHandler.setDefault(manager);
		Map<String,String > valueMap = this.doLoginStep0(userName, password) ;

		valueMap.put("email", userName);
		valueMap.put("password", password);
		this.doLoginStep1(valueMap);
		return false;
	}

	public static void main(String[] args) {
		AmazonLogin login = new AmazonLogin();
		try {
			logger.debug(login.doLogin("info-denki@e-mail.jp", "12344321"));
		} catch (AmazonException e) {
			e.printStackTrace();
		}
	}
}
